package com.pengshun.modules.api.transport.service.impl;

import com.pengshun.modules.api.coal.repository.UserRepository;
import com.pengshun.modules.api.coal.util.CommonUtil;
import com.pengshun.modules.api.mapper.TransportMapper;
import com.pengshun.modules.api.transport.dto.*;
import com.pengshun.modules.api.transport.repository.*;
import com.pengshun.modules.api.transport.service.TakeTransportOrderService;
import com.pengshun.modules.api.transport.service.mapstruct.FreightSettlementPhotoTodo;
import com.pengshun.modules.api.transport.service.mapstruct.FreightSettlementTodo;
import com.pengshun.modules.api.user.service.dto.AllotDto;
import com.pengshun.modules.common.BaseResult;
import com.pengshun.modules.domain.*;
import lombok.RequiredArgsConstructor;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

@Service
@RequiredArgsConstructor
public class TakeTransportOrderServiceImpl implements TakeTransportOrderService {

    private final TransportMapper transportMapper;
    private final TransportRepository transportRepository;
    private final UserRepository userRepository;
    private final FreightSettlementRepository freightSettlementRepository;
    private final TransportTakeCarriageRepository transportTakeCarriageRepository;
    private final TransportLoadRepository transportLoadRepository;
    private final TransportOrderRecordRepository transportOrderRecordRepository;
    private final TransportTakeOrderRepository transportTakeOrderRepository;
    private final FreightSettlementPhotoRepository freightSettlementPhotoRepository;
    private final FreightSettlementPhotoTodo freightSettlementPhotoTodo;
    private final FreightSettlementTodo freightSettlementTodo;
    private final MessageSource messageSource;
    private final TransportTakeStatusRepository transportTakeStatusRepository;

    @Override
    public BaseResult list(TransportDto dto) {
        int page = (dto.getPage()) * dto.getSize();
        List<TransportOrderDto> list = transportMapper.getTakeListByStatus(page < 0 ? 0 : page, dto.getSize(), dto.getStatus(), dto.getUserId());
        return new BaseResult(0, list);
    }

    @Override
    public BaseResult driverList(TransportDto dto) {
        //查询用户详情  司机按司机查询接单列表  否则按车主查询
        User user = userRepository.findById(dto.getUserId()).orElseGet(User::new);
        int page = (dto.getPage()) * dto.getSize();
        List<TransportOrderDto> list = new ArrayList<>();
        if (user.getUserType() == 1) {
            //司机接单列表
            list = transportMapper.getDriverTakeList(page < 0 ? 0 : page, dto.getSize(), dto.getStatus(), dto.getUserId(), dto.getTransportTakeOrderId());
        } else {
            //查询车主分配的货运列表
            list = transportMapper.getCarBossAllortDriverTakeList(page < 0 ? 0 : page, dto.getSize(), dto.getStatus(), dto.getUserId(), dto.getTransportTakeOrderId());
        }
        return new BaseResult(0, list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult update(FreightSettlementDto para) {
        TransportTakeCarriage carriage = transportTakeCarriageRepository.findById(para.getTransportTakeCarriageId()).orElseGet(TransportTakeCarriage::new);
        if (para.getStatus() < carriage.getStatus()) {
            return new BaseResult(1, messageSource.getMessage("TakeTransportOrderServiceImpl.update.status.error", null, Locale.CHINA));
        }
        TransportTakeStatus status = transportTakeStatusRepository.findByTransportTakeCarriageId(para.getTransportTakeCarriageId());
        if (para.getStatus() == 2) {
            if (para.getMineSendNum().compareTo(carriage.getNumber()) == 1) {
                return new BaseResult(1, messageSource.getMessage("FreightSettlementServiceImpl.save.numbers.err", null, Locale.CHINA));
            }
            status.setLoadTime(new Date());
            //装货操作
            TransportLoad load = new TransportLoad();
            load.setPhoto(para.getUrls());
            load.setMineSendNum(para.getMineSendNum());
            //表里唯一约束
            load.setTransportTakeCarriageId(para.getTransportTakeCarriageId());
            load.setLoadTime(new Date());
            transportLoadRepository.save(load);
            carriage.setStatus(para.getStatus());
        }
        if (para.getStatus() == 3) {
            //卸货生成结算单
            TransportLoad load = transportLoadRepository.findByTransportTakeCarriageId(para.getTransportTakeCarriageId());
            //矿发实收吨位不能大于接取吨位
            if (para.getRealNum().compareTo(carriage.getNumber()) == 1) {
                return new BaseResult(1, messageSource.getMessage("FreightSettlementServiceImpl.save.number.err", null, Locale.CHINA));
            }

            //判断是否申请结算过
            if (carriage.getIsApply() == 1) {
                return new BaseResult(1, messageSource.getMessage("FreightSettlementServiceImpl.save.exist", null, Locale.CHINA));
            }
            FreightSettlement settlement = freightSettlementRepository.findByTransportTakeCarriageId(para.getTransportTakeCarriageId());
            if (settlement != null) {
                return new BaseResult(1, messageSource.getMessage("FreightSettlementServiceImpl.save.exist", null, Locale.CHINA));
            }
            status.setUnloadTime(new Date());
            //计算费用是否准确  最终数量乘以运费
            para.setOtherFee(para.getOtherFee() == null ? new BigDecimal(0) : para.getOtherFee());
            //更新接单表申请状态
            carriage.setIsApply(1);
            carriage.setStatus(para.getStatus());
            transportTakeCarriageRepository.save(carriage);
            //结算表添加数据
            para.setApplyUserId(para.getUserId());
            para.setFreight(carriage.getFreight());
            para.setLoadFee(carriage.getLoadFee());
            para.setUnloadFee(carriage.getUnloadFee());
            para.setPoundsFee(carriage.getPoundsFee());
            para.setOtherFee(carriage.getOtherFee());
            //查询用户信息 设置电话姓名
            User user = userRepository.findById(para.getUserId()).orElseGet(User::new);
            para.setApplyUserPhone(user.getPhone());
            para.setApplyUserName(user.getName());
            para.setStatus(1);
            para.setApplyDate(new Date());

            //查询接单详情
            TransportTakeOrder takeOrder = transportTakeOrderRepository.findById(carriage.getTransportTakeOrderId()).orElseGet(TransportTakeOrder::new);
            para.setGatheringUserId(takeOrder.getGatheringUserId());
            para.setSettlementNo("PS" + CommonUtil.getFourRandom());
            para.setTransportId(takeOrder.getTransportId());
            para.setOrderId(takeOrder.getOrderId());
            para.setSettlementType(takeOrder.getOrderId() == null ? 2 : 1);
            //根据商户id  查询支付用户id
            Transport transport = transportRepository.findById(takeOrder.getTransportId()).orElseGet(Transport::new);
            para.setPayUserId(transport.getUserId());
            para.setMerchantName(transport.getMerchantName());
            FreightSettlement freights = freightSettlementTodo.toEntity(para);
            freights.setSettlementType(para.getSettlementType());
            freights.setOrderId(carriage.getOrderId());
            freights.setMineSendNum(load.getMineSendNum());
            freights.setPrice(transport.getPrice());
            freights.setOilProportion(transport.getOilProportion());
            freights.setCashProportion(transport.getCashProportion());
            BigDecimal diffNum=new BigDecimal(0);
            if(load.getMineSendNum().compareTo(para.getRealNum())==1){
                diffNum=load.getMineSendNum().subtract(para.getRealNum());
            }
            freights.setDiffNum(diffNum);

            //当实收吨位大于矿发吨位时则以矿发吨位结算，两者取其小
            BigDecimal realNum = para.getRealNum().compareTo(load.getMineSendNum()) == 1 ? load.getMineSendNum() : para.getRealNum();
            //todo 结算费用= 实到数量乘以运费
            BigDecimal totalFee = (realNum.multiply(carriage.getFreight()));
            //减去其他费用
            totalFee = totalFee.subtract(transport.getOtherFee());
            //如果差异吨位大于0
            if (freights.getDiffNum().compareTo(BigDecimal.ZERO) == 1) {
                //计算需要赔偿的费用 == 差异吨位*货物价格
                BigDecimal deffPrice = freights.getDiffNum().multiply(transport.getPrice());
                freights.setDiffPrice(deffPrice);
                totalFee = totalFee.subtract(deffPrice);
            }
            freights.setSettlementAmount(totalFee);
            freights.setCheckStatus(1);
            //如果运费为负数  设置异常状态未1
            if (freights.getSettlementAmount().compareTo(BigDecimal.ZERO) == -1) {
                freights.setIsAbnormal("1");
                freights.setAbnormalStatus("1");
            } else {
                freights.setIsAbnormal("0");
            }
            //计算油卡 现金 金额  取比例小的比例  来计算金额 取整数
//            if(freights.getCashProportion()>freights.getOilProportion()){
//                int oilFee=(freights.getSettlementAmount().divide(new BigDecimal(freights.getOilProportion())).setScale( 0, BigDecimal.ROUND_UP ).intValue());
//                freights.setOilCardFee(new BigDecimal(oilFee));
//                freights.setCashFee(freights.getSettlementAmount().subtract(freights.getOilCardFee()));
//            }else{
//                int cashFee=(freights.getSettlementAmount().divide(new BigDecimal(freights.getCashProportion())).setScale( 0, BigDecimal.ROUND_UP ).intValue());
//                freights.setCashFee(new BigDecimal(cashFee));
//                freights.setOilCardFee(freights.getSettlementAmount().subtract(freights.getCashFee()));
//            }
//            if("1".equals(transport.getIsContract())){
//                //如果是承包货运 直接结算完成
//                freights.setStatus(3);
//                freights.setCleanDate(new Date());
//                freights.setRemark("承包运费跳过结算");
//                //流程设置结算时间
//                status.setSettlementTime(new Date());
//                //接单改为已结算
//                carriage.setCleanStatus(2);
//            }
            FreightSettlement freightSettlement = freightSettlementRepository.save(freights);
            //结算票据表添加图片信息
            List<FreightSettlementPhotoDto> photoDtos = new ArrayList<>();
            String urls[] = para.getUrls().split(",");
            String loadurls[] = load.getPhoto().split(",");
            for (int i = 0; i < urls.length; i++) {
                FreightSettlementPhotoDto dto = new FreightSettlementPhotoDto(freightSettlement.getFreightSettlementId(), urls[i]);
                photoDtos.add(dto);
            }
            for (int i = 0; i < loadurls.length; i++) {
                FreightSettlementPhotoDto dto = new FreightSettlementPhotoDto(freightSettlement.getFreightSettlementId(), loadurls[i]);
                photoDtos.add(dto);
            }
            freightSettlementPhotoRepository.saveAll(freightSettlementPhotoTodo.toEntity(photoDtos));
        }
        //流程保存
        transportTakeStatusRepository.save(status);
        //接单更新
        transportTakeCarriageRepository.save(carriage);
        TransportOrderRecord transportOrderRecord = new TransportOrderRecord(null, carriage.getTransportTakeCarriageId(), null, para.getUserId(), para.getStatus());
        transportOrderRecordRepository.save(transportOrderRecord);
        return new BaseResult(0);

    }

    @Override
    public BaseResult detil(Long transportTakeOrderId) {
        TransportOrderDetil detil = transportMapper.selectTakeOrderDetil(transportTakeOrderId);
        return new BaseResult(0, detil);
    }

    @Override
    public BaseResult driverDetil(Long transportTakeCarriageId) {
        TransportOrderDetil detil = transportMapper.selectDriverTakeOrderDetil(transportTakeCarriageId);
        return new BaseResult(0, detil);
    }

    @Override
    public BaseResult findAllotList(Long id, Long transportTakeOrderId, Integer status) {
        TransportTakeOrder dto = transportTakeOrderRepository.findById(transportTakeOrderId).orElseGet(TransportTakeOrder::new);
        List<CarNumberDto> list = new ArrayList<>();
        if (status == 1) {
            list = transportMapper.findAllotList(id, transportTakeOrderId);
        } else {
            list = transportMapper.findAlreadyAllotList(transportTakeOrderId);
        }
        AllotDto dto1 = new AllotDto(dto.getTotalNumber(), dto.getTotalNumber().subtract(dto.getNumber()), dto.getNumber(), list);
        return new BaseResult(0, dto1);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult allotSave(CarNumberDto para) {
        //查询当前车辆有无运输中的货运
        Integer inTransport = transportMapper.findInTransportByCarnum(para.getCarNumber());
        if (inTransport != null && inTransport > 0) {
            return new BaseResult(1, messageSource.getMessage("TakeTransportOrderServiceImpl.allotSave.car", null, Locale.CHINA));
        }
        //查询当前司机有无运输中的货运  有则返回提示信息
        Integer inTransports = transportMapper.findInTransportByUserId(para.getUserId());
        if (inTransports != null && inTransports > 0) {
            return new BaseResult(1, messageSource.getMessage("TakeTransportOrderServiceImpl.allotSave.fail", null, Locale.CHINA));
        }
//        TransportTakeCarriage takeCarriage = transportTakeCarriageRepository.findByTransportTakeOrderIdAndCarOwnerNumAndStatusBetween(para.getTransportTakeOrderId(), para.getCarNumber(), 1, 3);
//        if (takeCarriage != null) {
//            return new BaseResult(1, messageSource.getMessage("TakeTransportOrderServiceImpl.allotSave.carriage", null, Locale.CHINA));
//        }
        TransportTakeOrder dto = transportTakeOrderRepository.findById(para.getTransportTakeOrderId()).orElseGet(TransportTakeOrder::new);
        BigDecimal totalNum = new BigDecimal(0);
        totalNum = totalNum.add(para.getNumber());
        String no = "PTT" + CommonUtil.getFourRandom();
        TransportTakeCarriage carriage = new TransportTakeCarriage(para.getTransportTakeOrderId(), para.getName(), para.getUserId(), no, 1, para.getCarOwnerId(), para.getCarNumber(),
                para.getTypeName(), para.getNumber(), new Date(), para.getAllotUserId(), para.getCarLoad(), para.getCarPhoto(), dto.getFreight(), dto.getInfoFee(), dto.getLoadFee(), dto.getUnloadFee(),
                dto.getPoundsFee(), dto.getOtherFee(), 0, dto.getOrderId(), 1);
        carriage.setAllotUserId(para.getAllotUserId());
        if (dto.getNumber().compareTo(totalNum) == -1) {
            return new BaseResult(1, messageSource.getMessage("TakeTransportOrderServiceImpl.allotSave.insufficient", null, Locale.CHINA));
        }
        transportTakeCarriageRepository.save(carriage);
        BigDecimal oldNum = dto.getNumber();
        BigDecimal newNum = dto.getNumber().subtract(totalNum);
        transportMapper.updateTransportTakeOrderNumber(oldNum, newNum, dto.getTransportTakeOrderId());
        //流程保存
        TransportTakeStatus status = new TransportTakeStatus();
        status.setTakeTime(new Date());
        status.setTransportTakeCarriageId(carriage.getTransportTakeCarriageId());
        transportTakeStatusRepository.save(status);

        return new BaseResult(0, messageSource.getMessage("TakeTransportOrderServiceImpl.allotSave.success", null, Locale.CHINA));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult allotUpdate(CarNumberDto para) {
        //查询接单信息
        TransportTakeOrder dto = transportTakeOrderRepository.findById(para.getTransportTakeOrderId()).orElseGet(TransportTakeOrder::new);
        //查询分配数量
        TransportTakeCarriage carriage = transportTakeCarriageRepository.findById(para.getTransportTakeCarriageId()).orElseGet(TransportTakeCarriage::new);
        //当前库存 加之前分配的 减去现在分配的
        BigDecimal nowNum = dto.getNumber().add(carriage.getNumber()).subtract(para.getNumber());
        //判断当前库存是否大于0
        if (BigDecimal.ZERO.compareTo(nowNum) == 1) {
            return new BaseResult(1, messageSource.getMessage("TakeTransportOrderServiceImpl.allotSave.insufficient", null, Locale.CHINA));
        }
        carriage.setNumber(para.getNumber());
        if (para.getName() != null) {
            carriage.setName(para.getName());
        }
        if (para.getUserId() != null) {
            carriage.setUserId(para.getUserId());
        }
        carriage.setAllotUserId(para.getAllotUserId());
        transportTakeCarriageRepository.save(carriage);

        BigDecimal oldNum = dto.getNumber();

        transportMapper.updateTransportTakeOrderNumber(oldNum, nowNum, dto.getTransportTakeOrderId());
        return new BaseResult(0, messageSource.getMessage("TakeTransportOrderServiceImpl.allotUpdate.success", null, Locale.CHINA));
    }

    @Override
    public BaseResult ownerList(TransportDto dto) {
        int page = (dto.getPage()) * dto.getSize();
        List<TransportOrderDto> list = transportMapper.getTakeListByStatusAndCar(page < 0 ? 0 : page, dto.getSize(), dto.getStatus(), dto.getUserId());
        return new BaseResult(0, list);
    }

    @Override
    public BaseResult ownerDetil(Long TransportTakeCarriageId) {
        TransportOrderDetil detil = transportMapper.selectOwnerDetil(TransportTakeCarriageId);
        return new BaseResult(0, detil);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult cancle(Long id, Long transportTakeCarriageId) {
        TransportTakeCarriage carriage = transportTakeCarriageRepository.findById(transportTakeCarriageId).orElseGet(TransportTakeCarriage::new);
        if (carriage.getStatus().longValue() != 1) {
            return new BaseResult(1, "已装货过不能取消");
        }

        carriage.setStatus(0);
        transportTakeCarriageRepository.save(carriage);
        TransportTakeOrder order = transportTakeOrderRepository.findById(carriage.getTransportTakeOrderId()).orElseGet(TransportTakeOrder::new);
        if (carriage.getUserId().longValue() == order.getUserId().longValue()) {
            //说明是司机接单
            order.setStatus(0);
            order.setType(3);
            transportTakeOrderRepository.save(order);
            //运单增加库存
            Transport transport = transportRepository.findById(order.getTransportId()).orElseGet(Transport::new);

            //加库存
            BigDecimal oldCoalNumber = transport.getTotalNumber();
            BigDecimal nowCoalNumber = transport.getTotalNumber().add(carriage.getNumber());
            transportMapper.updateTransportWeight(transport.getId(), nowCoalNumber, oldCoalNumber);
        }
        //流程更新
        TransportTakeStatus status = transportTakeStatusRepository.findByTransportTakeCarriageId(carriage.getTransportTakeCarriageId());
        status.setCancleTime(new Date());
        transportTakeStatusRepository.save(status);
        return new BaseResult(0, messageSource.getMessage("cancle.success", null, Locale.CHINA));
    }

    @Override
    public BaseResult del(Long id, Long transportTakeCarriageId) {
        TransportTakeCarriage carriage = transportTakeCarriageRepository.findById(transportTakeCarriageId).orElseGet(TransportTakeCarriage::new);
        if (carriage.getStatus().longValue() != 0) {
            return new BaseResult(1, "不是取消订单不能删除");
        }
        carriage.setStatus(5);
        transportTakeCarriageRepository.save(carriage);
        //流程更新
        TransportTakeStatus status = transportTakeStatusRepository.findByTransportTakeCarriageId(carriage.getTransportTakeCarriageId());
        status.setDeleteTime(new Date());
        transportTakeStatusRepository.save(status);
        return new BaseResult(0, messageSource.getMessage("delete.success", null, Locale.CHINA));
    }
}
